document.addEventListener('DOMContentLoaded', () => {
    const gameBoard = document.getElementById('game-board');
    const messageEl = document.getElementById('message');
    const resetButton = document.getElementById('reset-button');
    const bgmAudio = document.getElementById('bgm'); // 获取 audio 元素
    const gameOverlay = document.getElementById('game-overlay'); // 获取覆盖层元素
    // console.log('Game Overlay Element:', gameOverlay); // 调试：检查是否获取到元素

    // --- 游戏配置 ---
    const GRID_RADIUS = 5; // 棋盘半径（中心到边缘的层数）
    const DISABLED_PERCENTAGE = 0.15; // 初始障碍物（不可用格子）比例
    const INITIAL_POLICE_COUNT = 8; // 初始警察数量

    // --- 状态变量 ---
    let grid = new Map(); // 使用 Map 存储格子信息，键为 "q,r" 字符串
    let thiefPos = { q: 0, r: 0 };
    let policePositions = []; // 存储警察的位置 {q, r}
    let isPlayerTurn = true;
    let gameEnded = false;

    // --- 坐标系统 (Axial Coordinates) ---
    // q (column), r (row)
    // Neighbors offsets: [ [1, 0], [0, 1], [-1, 1], [-1, 0], [0, -1], [1, -1] ]

    const axialDirections = [
        { q: 1, r: 0 }, { q: 0, r: 1 }, { q: -1, r: 1 },
        { q: -1, r: 0 }, { q: 0, r: -1 }, { q: 1, r: -1 }
    ];

    // --- Helper Functions ---

    // 坐标转 Map 键
    function coordToKey(q, r) {
        return `${q},${r}`;
    }

    // Map 键转坐标
    function keyToCoord(key) {
        const [q, r] = key.split(',').map(Number);
        return { q, r };
    }

    // 获取邻居坐标
    function getNeighbors(q, r) {
        return axialDirections.map(dir => ({ q: q + dir.q, r: r + dir.r }));
    }

    // 检查坐标是否在棋盘内
    function isInBounds(q, r) {
        // 使用 Cube coordinates (x+y+z=0) 检查边界更方便
        // x = q, z = r, y = -q-r
        const x = q;
        const z = r;
        const y = -q - r;
        return Math.max(Math.abs(x), Math.abs(y), Math.abs(z)) <= GRID_RADIUS;
    }

    // Axial 坐标转像素坐标 (Pointy Top)
    function axialToPixel(q, r, hexSize) { // size = distance from center to corner
        const boardWidth = gameBoard.offsetWidth;
        const boardHeight = gameBoard.offsetHeight;
        const hexWidth = Math.sqrt(3) * hexSize;
        const hexHeight = 2 * hexSize;

        // 基础偏移量，使中心 (0,0) 位于棋盘中央
        const offsetX = boardWidth / 2 - hexWidth / 2; // Center based on width
        const offsetY = boardHeight / 2 - hexHeight / 2; // Center based on height

        // Pointy Top 公式
        const x = offsetX + hexSize * (Math.sqrt(3) * q + Math.sqrt(3) / 2 * r);
        const y = offsetY + hexSize * (3 / 2 * r);

        return { x, y };
    }


    // --- 游戏逻辑 ---

    // 创建棋盘格子数据
    function createGrid() {
        grid.clear();
        policePositions = [];
        for (let q = -GRID_RADIUS; q <= GRID_RADIUS; q++) {
            for (let r = -GRID_RADIUS; r <= GRID_RADIUS; r++) {
                if (isInBounds(q, r)) {
                    const key = coordToKey(q, r);
                    grid.set(key, {
                        q,
                        r,
                        isEnabled: true,
                        isPolice: false,
                        isThief: false,
                        isEdge: Math.max(Math.abs(q), Math.abs(-q - r), Math.abs(r)) === GRID_RADIUS // 检查是否为边缘格子
                    });
                }
            }
        }
    }

    // 随机设置障碍物
    function setObstacles() {
        const totalCells = grid.size;
        const numDisabled = Math.floor(totalCells * DISABLED_PERCENTAGE);
        const keys = Array.from(grid.keys());
        let count = 0;
        while (count < numDisabled) {
            const randomIndex = Math.floor(Math.random() * keys.length);
            const key = keys[randomIndex];
            const cell = grid.get(key);
            // 不能禁用中心格子或已经是障碍的格子
            if (cell.q !== 0 || cell.r !== 0) {
                if (cell.isEnabled) {
                    cell.isEnabled = false;
                    count++;
                }
            }
        }
         // 确保可用格子至少占 70% (虽然上面是按比例禁用，这里再检查一下)
        const enabledCount = Array.from(grid.values()).filter(c => c.isEnabled).length;
        if (enabledCount / totalCells < 0.7) {
            console.warn("可用格子少于70%，可能需要调整障碍物比例或棋盘大小。正在尝试重新生成...");
            // 简单处理：如果格子太少，就重新生成一次（可能需要更健壮的逻辑）
            createGrid();
            setObstacles(); // 递归调用，注意避免死循环
            return; // 退出当前函数
        }
    }

    // 放置小偷
    function placeThief() {
        thiefPos = { q: 0, r: 0 };
        const centerCell = grid.get(coordToKey(0, 0));
        if (centerCell && centerCell.isEnabled) {
             centerCell.isThief = true;
        } else {
            // 如果中心被禁用了（理论上不应该），找一个附近的可用格子
            console.error("中心格子被禁用，无法放置小偷！正在寻找替代位置...");
            const neighbors = getNeighbors(0, 0);
            let placed = false;
            for (const n of neighbors) {
                const key = coordToKey(n.q, n.r);
                const cell = grid.get(key);
                if (cell && cell.isEnabled) {
                    thiefPos = { q: n.q, r: n.r };
                    cell.isThief = true;
                    placed = true;
                    break;
                }
            }
            if (!placed) {
                 console.error("无法在中心附近找到可用格子放置小偷！游戏可能无法开始。");
                 // 可以尝试扩大搜索范围或抛出错误
            }
        }
    }

     // 随机放置初始警察
    function placeInitialPolice() {
        const availableKeys = Array.from(grid.keys()).filter(key => {
            const cell = grid.get(key);
            return cell.isEnabled && !cell.isThief; // 必须是可用且非小偷格子
        });

        let count = 0;
        while (count < INITIAL_POLICE_COUNT && availableKeys.length > 0) {
            const randomIndex = Math.floor(Math.random() * availableKeys.length);
            const key = availableKeys.splice(randomIndex, 1)[0]; // 从可用列表中移除并获取
            const cell = grid.get(key);
            if (cell) { // 再次确认
                cell.isPolice = true;
                policePositions.push({ q: cell.q, r: cell.r });
                count++;
            }
        }
        if (count < INITIAL_POLICE_COUNT) {
            console.warn(`未能放置足够数量的初始警察 (${count}/${INITIAL_POLICE_COUNT})`);
        }
    }


    // 渲染棋盘
    function renderBoard() {
        gameBoard.innerHTML = ''; // 清空旧棋盘
        const boardRect = gameBoard.getBoundingClientRect();

        // --- 重新估算 hexSize 以适应容器 ---
        // 估算水平方向需要的 size
        const sizeBasedOnWidth = boardRect.width / (Math.sqrt(3) * (GRID_RADIUS * 2 + 1));
        // 估算垂直方向需要的 size (每层高度贡献 1.5 * size)
        const sizeBasedOnHeight = boardRect.height / (1.5 * (GRID_RADIUS * 2) + 2); // (2*R+1) rows, each contributes 1.5*size, total height approx 1.5*size*2R + 2*size

        // 取较小的 size 以确保完全容纳
        const hexSize = Math.min(sizeBasedOnWidth, sizeBasedOnHeight) * 0.95; // 缩小一点留出间隙
        const hexWidth = Math.sqrt(3) * hexSize;
        const hexHeight = 2 * hexSize;
        // --- 估算结束 ---

        grid.forEach(cell => {
            const hexElement = document.createElement('div');
            hexElement.classList.add('hexagon');
            hexElement.dataset.q = cell.q;
            hexElement.dataset.r = cell.r;

            // 使用新的 axialToPixel 和计算出的 hexSize
            const { x, y } = axialToPixel(cell.q, cell.r, hexSize);
            hexElement.style.left = `${x}px`;
            hexElement.style.top = `${y}px`;
             // 设置计算出的尺寸
            hexElement.style.width = `${hexWidth}px`;
            hexElement.style.height = `${hexHeight}px`;


            if (!cell.isEnabled) {
                hexElement.classList.add('disabled');
            } else {
                if (cell.isPolice) {
                    hexElement.classList.add('police');
                } else if (cell.isThief) {
                    hexElement.classList.add('thief');
                }
                // 添加点击事件监听器 (只对可用、非警察、非小偷的格子)
                if (cell.isEnabled && !cell.isPolice && !cell.isThief) {
                     hexElement.addEventListener('click', handleCellClick);
                }
            }
            gameBoard.appendChild(hexElement);
        });
    }

    // --- 事件处理 ---
    function handleCellClick(event) {
        if (!isPlayerTurn || gameEnded) return;

        const target = event.target;
        const q = parseInt(target.dataset.q);
        const r = parseInt(target.dataset.r);
        const key = coordToKey(q, r);
        const cell = grid.get(key);

        if (!cell || !cell.isEnabled || cell.isPolice || cell.isThief) {
            setMessage("这里不能放置警察！");
            return;
        }

        // 检查是否与现有警察相邻
        const neighbors = getNeighbors(q, r);
        const isAdjacentToPolice = neighbors.some(n => {
            const neighborKey = coordToKey(n.q, n.r);
            const neighborCell = grid.get(neighborKey);
            return neighborCell && neighborCell.isPolice;
        });

        // 特殊情况：如果是第一次放置警察（棋盘上还没有警察时），可以放在任意位置
        const isFirstPolicePlacement = policePositions.length === 0;


        if (!isAdjacentToPolice && !isFirstPolicePlacement) {
             setMessage("必须放置在现有警察旁边！");
             return;
        }


        // 放置警察
        cell.isPolice = true;
        policePositions.push({ q, r });
        target.classList.add('police');
        target.removeEventListener('click', handleCellClick); // 放置后移除监听
        setMessage(""); // 清除消息

        // 检查玩家是否获胜 (放置后小偷无路可走)
        if (checkWinCondition()) {
            endGame(true);
            return;
        }

        // 切换到小偷回合
        isPlayerTurn = false;
        setMessage("小偷正在思考...");
        // 使用 setTimeout 模拟小偷思考时间，并执行移动
        setTimeout(thiefTurn, 500);
    }

    function thiefTurn() {
        if (gameEnded) return;

        // 实现小偷移动逻辑 (A* 或 BFS 寻找最短路径到边缘)
        const path = findPathToEdge(thiefPos.q, thiefPos.r);

        if (path && path.length > 1) { // 路径长度大于1表示可以移动
            const nextStep = path[1]; // path[0] 是当前位置
            const currentKey = coordToKey(thiefPos.q, thiefPos.r);
            const nextKey = coordToKey(nextStep.q, nextStep.r);

            // 更新格子状态
            const currentCell = grid.get(currentKey);
            const nextCell = grid.get(nextKey);

            if (currentCell) currentCell.isThief = false;
            if (nextCell) nextCell.isThief = true;

            // 更新小偷位置
            thiefPos = { q: nextStep.q, r: nextStep.r };

            // 检查小偷是否到达边缘
            if (nextCell && nextCell.isEdge) {
                renderBoard(); // 渲染最后一步
                endGame(false); // 小偷获胜
                return;
            }
        } else {
            // 没有可行的路径，玩家获胜
            endGame(true);
            return;
        }

        // 重新渲染棋盘
        renderBoard();

        // 检查小偷移动后是否被抓 (理论上 findPathToEdge 会避开警察，但可以加一层保险)
        // if (grid.get(coordToKey(thiefPos.q, thiefPos.r)).isPolice) {
        //     endGame(true); // 这种情况不应该发生
        //     return;
        // }

        // 切换回玩家回合
        isPlayerTurn = true;
        setMessage("轮到你了！");
    }

    // 寻找小偷到边缘的最短路径 (使用 BFS)
    function findPathToEdge(startQ, startR) {
        const queue = [[{ q: startQ, r: startR }]]; // 队列存储路径
        const visited = new Set([coordToKey(startQ, startR)]);

        while (queue.length > 0) {
            const currentPath = queue.shift();
            const lastNode = currentPath[currentPath.length - 1];

            // 检查是否到达边缘
            const lastCell = grid.get(coordToKey(lastNode.q, lastNode.r));
            if (lastCell && lastCell.isEdge) {
                return currentPath; // 找到路径
            }

            const neighbors = getNeighbors(lastNode.q, lastNode.r);
            for (const neighbor of neighbors) {
                const key = coordToKey(neighbor.q, neighbor.r);
                const cell = grid.get(key);

                // 必须是棋盘内、可用、非警察格子，且未访问过
                if (cell && cell.isEnabled && !cell.isPolice && !visited.has(key)) {
                    visited.add(key);
                    const newPath = [...currentPath, neighbor];
                    queue.push(newPath);
                }
            }
        }
        return null; // 没有找到路径
    }


    // 检查玩家获胜条件 (小偷无路可走)
    function checkWinCondition() {
        const path = findPathToEdge(thiefPos.q, thiefPos.r);
        return path === null; // 如果找不到路径，说明小偷被围住
    }

    // 结束游戏
    function endGame(playerWins) {
        console.log('Game Ended. Player Wins:', playerWins); // 调试：确认 endGame 被调用
        gameEnded = true;
        if (bgmAudio) { // 停止背景音乐
            bgmAudio.pause();
            bgmAudio.currentTime = 0; // 可选：将播放位置重置到开头
        }
        if (playerWins) {
            setMessage("恭喜你，抓到毛贼了！");
            if (gameOverlay) {
                console.log('Adding classes for win:', gameOverlay.classList); // 调试：添加前
                gameOverlay.classList.add('visible', 'game-won');
                console.log('Added classes for win:', gameOverlay.classList); // 调试：添加后
            }
        } else {
            setMessage("糟糕，毛贼逃跑了！");
            if (gameOverlay) {
                console.log('Adding classes for loss:', gameOverlay.classList); // 调试：添加前
                gameOverlay.classList.add('visible', 'game-lost');
                console.log('Added classes for loss:', gameOverlay.classList); // 调试：添加后
            }
        }
        // 可以移除所有格子的点击事件，防止误操作
        const hexes = gameBoard.querySelectorAll('.hexagon');
        hexes.forEach(hex => hex.removeEventListener('click', handleCellClick));
    }

    // 设置消息
    function setMessage(msg) {
        messageEl.textContent = msg;
    }

    // 重置游戏
    function resetGame() {
        gameEnded = false;
        isPlayerTurn = true;
        setMessage("");
        if (gameOverlay) { // 隐藏覆盖层并移除效果类
            gameOverlay.classList.remove('visible', 'game-lost', 'game-won');
        }
        createGrid();
        setObstacles();
        // 确保障碍物设置后重新获取 grid 状态
        if (grid.size === 0) { // 如果 setObstacles 触发了重新生成
            //  console.log("重新获取 grid 引用...");
             // grid 变量应该已经是更新后的，这里只是日志
        }
        placeThief();
        placeInitialPolice(); // 在放置小偷之后放置警察
        renderBoard();

        // 尝试播放背景音乐
        if (bgmAudio) {
            // 注意：浏览器可能会阻止自动播放，直到用户与页面交互
            // 一个常见的处理方式是在第一次用户点击时启动播放
            bgmAudio.play().catch(error => {
                console.warn("背景音乐自动播放失败:", error);
                // 可以考虑添加一个按钮或在首次点击格子时播放
            });
        }
    }

    // --- 初始化 ---
    resetButton.addEventListener('click', resetGame);
    resetGame(); // 首次加载时初始化游戏

});